package com.paddyi.jwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtUtil {
    @Autowired
    private JwtConfigProperty jwtConfigProperty;

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    private Claims getClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(jwtConfigProperty.getJwtKey()).parseClaimsJws(token).getBody();
    }

    /**
     * 从令牌中获取认证的唯一标识
     *
     * @param token 令牌
     * @return 用户id
     */
    public String getSubjectFromToken(String token) {
        String username;
        try {
            Claims claims = getClaimsFromToken(token);
            username = claims.getSubject();
        } catch (Exception e) {
            e.printStackTrace();
            username = null;
        }
        return username;
    }

    /**
     * 验证令牌是否时间有效
     *
     * @param token 令牌
     * @return 是否有效
     */
    public Boolean validateToken(String token) throws Exception {
        try {
            Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            Date notBefore = claims.getNotBefore();
            return new Date().after(notBefore) && new Date().before(expiration);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 生成令牌
     *
     * @param username .
     * @return .
     */
    public String generateToken(String username,boolean isServer) {
        int expirationMinute = jwtConfigProperty.getClientExpirationMinute();
        if (isServer){
            expirationMinute = jwtConfigProperty.getServerExpirationMinute();
        }
        long time = System.currentTimeMillis();
        return Jwts.builder()
                //JWT唯一标识，设置不重复的值保证重复攻击
                .setId(String.valueOf(time))
                //JWT签发者
                .setIssuer(jwtConfigProperty.getIssuer())
                // JWT具体内容
                .setSubject(username)
                //过期时间
                .setExpiration(new Date(time + expirationMinute * 60 * 1000))
                //JWT什么时间之后开始生效
                .setNotBefore(new Date(time))
                .setIssuedAt(new Date(time))
                .signWith(SignatureAlgorithm.HS512, jwtConfigProperty.getJwtKey())
                .compact();
    }


}
